/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.fzhucc.modules.thinktank.service;

import com.fzhucc.exception.BadRequestException;
import com.fzhucc.modules.pms.domain.Project;
import com.fzhucc.modules.pms.domain.dto.ProjectDto;
import com.fzhucc.modules.pms.domain.dto.ProjectExpertScoreDto;
import com.fzhucc.modules.pms.repository.ProjectRepository;
import com.fzhucc.modules.pms.service.ProjectService;
import com.fzhucc.modules.thinktank.domain.Capital;
import com.fzhucc.modules.thinktank.domain.CapitalProjectLog;
import com.fzhucc.modules.thinktank.domain.Company;
import com.fzhucc.modules.thinktank.domain.CompanyProjectLog;
import com.fzhucc.modules.thinktank.domain.dto.CapitalProjectDistributionDto;
import com.fzhucc.modules.thinktank.domain.dto.CompanyProjectDistributionDto;
import com.fzhucc.modules.thinktank.repository.CompanyRepository;
import com.fzhucc.utils.*;
import lombok.RequiredArgsConstructor;
import com.fzhucc.modules.thinktank.repository.CompanyProjectLogRepository;
import com.fzhucc.modules.thinktank.domain.dto.CompanyProjectLogDto;
import com.fzhucc.modules.thinktank.domain.dto.CompanyProjectLogQueryCriteria;
import com.fzhucc.modules.thinktank.service.mapstruct.CompanyProjectLogMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author yyg
* @date 2023-01-03
**/
@Service
@RequiredArgsConstructor
public class CompanyProjectLogService {

    private final CompanyProjectLogRepository companyProjectLogRepository;
    private final CompanyProjectLogMapper companyProjectLogMapper;

    private final CompanyRepository companyRepository;

    private final ProjectRepository projectRepository;

    private final ProjectService projectService;

    public Map<String,Object> queryAll(CompanyProjectLogQueryCriteria criteria, Pageable pageable){
        Page<CompanyProjectLog> page = companyProjectLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(companyProjectLogMapper::toDto));
    }

    public List<CompanyProjectLogDto> queryAll(CompanyProjectLogQueryCriteria criteria){
        return companyProjectLogMapper.toDto(companyProjectLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    public CompanyProjectLogDto findById(Integer id) {
        CompanyProjectLog companyProjectLog = companyProjectLogRepository.findById(id).orElseGet(CompanyProjectLog::new);
        ValidationUtil.isNull(companyProjectLog.getId(),"CompanyProjectLog","id",id);
        return companyProjectLogMapper.toDto(companyProjectLog);
    }

    @Transactional(rollbackFor = Exception.class)
    public CompanyProjectLogDto create(CompanyProjectLog resources) {
        return companyProjectLogMapper.toDto(companyProjectLogRepository.save(resources));
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(CompanyProjectLog resources) {
        CompanyProjectLog companyProjectLog = companyProjectLogRepository.findById(resources.getId()).orElseGet(CompanyProjectLog::new);
        ValidationUtil.isNull( companyProjectLog.getId(),"CompanyProjectLog","id",resources.getId());
        companyProjectLog.copy(resources);
        companyProjectLogRepository.save(companyProjectLog);
    }

    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            companyProjectLogRepository.deleteById(id);
        }
    }

    public void download(List<CompanyProjectLogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (CompanyProjectLogDto companyProjectLog : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("分配时间", companyProjectLog.getRelationTime());
            map.put("上市公司id", companyProjectLog.getCompanyId());
            map.put("项目id", companyProjectLog.getProjectId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    public Map<String, Object> getCompanyProjectByLoginUser(Pageable pageable) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Page<Project> page = projectRepository.findAllByCompanyUser(userId, pageable);
        return PageUtil.toPage(page);
    }

    public List<Long> getDifferenceSet(List<Long> allList, List<Long> list) {
        List<Long> resultList = new ArrayList<>();
        Map<String, Long> map = new HashMap<>();
        list.forEach(i2 -> {
            map.put(i2 + "", i2);
        });
        allList.forEach(i1 -> {
            Long m = map.get(i1 + "");
            //如果为空，则证明list2中无该数据
            if (m == null) {
                resultList.add(i1);
            }
        });
        return resultList;
    }

    @Transactional
    public void dodistribution(CompanyProjectDistributionDto companyProjectDistributionDto) {
        String project_id = companyProjectDistributionDto.getProjectId();
        List<Long> list = companyProjectDistributionDto.getListCompanyId();
        List<Long> repeatlist = new ArrayList<Long>();
        Optional<Project> optionalProject = projectRepository.findById(project_id);
        if (optionalProject.isEmpty()) {
            throw new BadRequestException("项目未找到");
        }
        if (list == null) {
            throw new BadRequestException("上市公司id list未找到");
        }
        //先删除所有该项目的绑定的上市公司
        List<CompanyProjectLog> listCompanyProjectLog = companyProjectLogRepository.findByProjectId(project_id);
        for (CompanyProjectLog companyProjectLog : listCompanyProjectLog) {
            Long companyId = companyProjectLog.getCompanyId();
            if (list.indexOf(companyId) == -1) { //不在则删除
                companyProjectLogRepository.deleteById(companyProjectLog.getId());
            } else {
                repeatlist.add(companyId);
            }
        }
        list = getDifferenceSet(list, repeatlist);
        for (Long ids : list) {
            //在新增新的上市公司
            CompanyProjectLog companyProjectLog = new CompanyProjectLog();
            companyProjectLog.setProjectId(project_id);
            companyProjectLog.setCompanyId(ids);
            companyProjectLog.setRelationTime(new Timestamp(new Date().getTime()));
            companyProjectLog.setProjectLevel(optionalProject.get().getLevel());
            companyProjectLogRepository.save(companyProjectLog);
        }
    }

    public List<Company> getCompanyByProjectId(String projectId) {
        List<Company> company_list = new ArrayList<Company>();
        List<CompanyProjectLog> list = companyProjectLogRepository.findByProjectId(projectId);
        if (list == null) {
            throw new BadRequestException("上市公司评分表项目未找到");
        }
        for (int i = 0; i < list.size(); i++) {
            CompanyProjectLog companyProjectLog = list.get(i);
            Long companyId = companyProjectLog.getCompanyId();
            Optional<Company> res = companyRepository.findById(companyId);
            if (res.isPresent()){
                company_list.add(res.get());
            }
        }
        return company_list;
    }

    public Map<String, Object> getProjectByLoginUser(Pageable pageable) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Page<Project> page = projectRepository.findAllByCompanyUser(userId, pageable);
        return PageUtil.toPage(page);
    }

    public void expertRating(ProjectExpertScoreDto projectExpertScoreDto) {
        BigDecimal score = projectExpertScoreDto.getScore();
        String projectId = projectExpertScoreDto.getProjectId();
        if (score == null) {
            throw new BadRequestException("评分为null");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Optional<Project> optionalProject = projectRepository.findById(projectId);
        if (optionalProject.isEmpty()) {
            throw new BadRequestException("项目未找到");
        }
        Company company = companyRepository.findByUserId(userId);
        if (company == null) {
            throw new BadRequestException("未找到上市公司专家");
        }
        Long expertId = company.getId();
        //专家评分只能查找当前阶段level进行评分
        List<CompanyProjectLog> list = companyProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expertId, projectId, optionalProject.get().getLevel());
        if (list == null || list.size() != 1) {
            throw new BadRequestException("上市公司专家未分配指定项目");
        }
        CompanyProjectLog companyProjectLog = list.get(0);
        companyProjectLog.setScore(score);
        companyProjectLog.setScoreTime(new Date());
        companyProjectLog.setAdvice(projectExpertScoreDto.getAdvice());
        companyProjectLogRepository.save(companyProjectLog);
    }

    public ProjectDto getProjectScoreByProjectId(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        List<CompanyProjectLog> list = companyProjectLogRepository.findByProjectId(projectId);
        projectDto.setCompanyScoreSituation(list);
        return projectDto;
    }

    public ProjectDto getProjectScoreByProjectIdSiftLevel(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        List<CompanyProjectLog> list1 = companyProjectLogRepository.findByProjectIdProjectLevel(projectId, 1);
        projectDto.setListCompanyLevel1(list1);
        List<CompanyProjectLog> list2 = companyProjectLogRepository.findByProjectIdProjectLevel(projectId, 2);
        projectDto.setListCompanyLevel2(list2);
        List<CompanyProjectLog> list3 = companyProjectLogRepository.findByProjectIdProjectLevel(projectId, 3);
        projectDto.setListCompanyLevel3(list3);
        return projectDto;
    }

    public boolean getIsScoreByProjectId(String projectId) {
        Optional<Project> optionalProject = projectRepository.findById(projectId);
        if (optionalProject.isEmpty()) {
            throw new BadRequestException("项目未找到");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        Company expert = companyRepository.findByUserId(userId);
        if (expert == null) {
            throw new BadRequestException("上市公司专家未找到");
        }
        List<CompanyProjectLog> list = companyProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, optionalProject.get().getLevel());
        if (list != null && list.size() == 1) {
            CompanyProjectLog companyProjectLog = list.get(0);
            if (companyProjectLog != null) {
                BigDecimal score = companyProjectLog.getScore();
                if (score != null) {
                    return true;
                }
            }
        }
        return false;
    }

    public ProjectDto getByProjectIdAndLoginUser(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        Company expert = companyRepository.findByUserId(userId);
        if (expert == null) {
            throw new BadRequestException("上市公司专家未找到");
        }
        List<CompanyProjectLog> list = companyProjectLogRepository.findByExpertIdAndProjectId(expert.getId(), projectId);
        projectDto.setCompanyScoreSituation(list);
        return projectDto;
    }

    public ProjectDto getByProjectIdAndLoginUserSiftLevel(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        Company expert = companyRepository.findByUserId(userId);
        if (expert == null) {
            throw new BadRequestException("上市公司专家未找到");
        }
        List<CompanyProjectLog> list1 = companyProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, 1);
        projectDto.setListCompanyLevel1(list1);
        List<CompanyProjectLog> list2 = companyProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, 2);
        projectDto.setListCompanyLevel2(list2);
        List<CompanyProjectLog> list3 = companyProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, 3);
        projectDto.setListCompanyLevel3(list3);
        return projectDto;
    }
}